package customer

import (
	"errors"
	"github.com/gin-gonic/gin"
	v1 "golang-sgg-daijia/api/v1"
	"golang-sgg-daijia/internal/handler"
	"golang-sgg-daijia/internal/service"
	"net/http"
	"strconv"
)

type OrderHandler struct {
	*handler.Handler
	orderService service.OrderService
	locationService service.LocationService
	paymentService service.PaymentService
}

func NewOrderHandler(
	handler *handler.Handler,
	orderService service.OrderService,
	locationService service.LocationService,
	paymentService service.PaymentService,
) *OrderHandler {
	return &OrderHandler{
		Handler:      handler,
		orderService: orderService,
		locationService: locationService,
		paymentService: paymentService,
	}
}

// SearchCustomerCurrentOrder 乘客端查找当前订单
func (h *OrderHandler) SearchCustomerCurrentOrder(ctx *gin.Context) {
	customerID := ctx.GetInt64("ID")
	currentOrderInfoVo, err := h.orderService.SearchCustomerCurrentOrder(ctx, customerID)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, currentOrderInfoVo)
}

// ExpectOrder 预估订单数据
func (h *OrderHandler) ExpectOrder(ctx *gin.Context) {
	req := new(v1.CalculateDrivingLineForm)
	if err := ctx.ShouldBindJSON(req); err != nil {
		v1.HandleError(ctx, http.StatusBadRequest, v1.ErrBadRequest, nil)
		return
	}
	expectOrderVo, err := h.orderService.ExpectOrder(ctx, req)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, expectOrderVo)
}

// SubmitOrder 乘客下单
func (h *OrderHandler) SubmitOrder(ctx *gin.Context) {
	req := new(v1.SubmitOrderForm)
	if err := ctx.ShouldBindJSON(req); err != nil {
		v1.HandleError(ctx, http.StatusBadRequest, v1.ErrBadRequest, nil)
		return
	}
	customerID := ctx.GetInt64("ID")
	req.CustomerId = customerID
	orderID, err := h.orderService.SubmitOrder(ctx, req)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, orderID)
}

// GetOrderStatus 查询订单状态
func (h *OrderHandler) GetOrderStatus(ctx *gin.Context) {
	orderIDStr := ctx.Param("orderId")
	orderID, err := strconv.Atoi(orderIDStr)
	if err != nil {
		v1.HandleError(ctx, http.StatusBadRequest, v1.ErrBadRequest, nil)
		return
	}
	orderStatus, err := h.orderService.GetOrderStatus(ctx, orderID)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, orderStatus)
}

// GetOrderInfo 获取订单信息
func (h *OrderHandler) GetOrderInfo(ctx *gin.Context) {
	orderIDStr := ctx.Param("orderId")
	orderID, err := strconv.Atoi(orderIDStr)
	if err != nil {
		v1.HandleError(ctx, http.StatusBadRequest, v1.ErrBadRequest, nil)
		return
	}
	customerID := ctx.GetInt64("ID")
	orderInfoVo, err := h.orderService.GetCustomerOrderInfo(ctx, orderID, customerID)
	if err != nil {
		if errors.Is(err, v1.ErrIllegalRequest) {
			v1.HandleError(ctx, v1.IllegalRequest, v1.ErrIllegalRequest, nil)
			return
		}
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, orderInfoVo)
}

// GetDriverInfo 根据订单id获取司机基本信息
func (h *OrderHandler) GetDriverInfo(ctx *gin.Context) {
	customerID := ctx.GetInt64("ID")
	orderIDStr := ctx.Param("orderId")
	orderID, err := strconv.Atoi(orderIDStr)
	if err != nil {
		v1.HandleError(ctx, http.StatusBadRequest, v1.ErrBadRequest, nil)
		return
	}
	driverInfoVo, err := h.orderService.GetDriverInfo(ctx, orderID, customerID)
	if err != nil {
		if err == v1.ErrDataError {
			v1.HandleError(ctx, v1.DataError, v1.ErrDataError, nil)
			return
		}
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, driverInfoVo)
}

// GetCacheOrderLocation 司机赶往代驾起始点：获取订单经纬度位置
func (h *OrderHandler) GetCacheOrderLocation(ctx *gin.Context) {
	orderIDStr := ctx.Param("orderId")
	orderID, err := strconv.Atoi(orderIDStr)
	if err != nil {
		v1.HandleError(ctx, http.StatusBadRequest, v1.ErrBadRequest, nil)
		return
	}
	orderLocation, err := h.locationService.GetCacheOrderLocation(ctx, int64(orderID))
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, orderLocation)
}

// CalculateDrivingLine 计算最佳驾驶线路
func (h *OrderHandler) CalculateDrivingLine(ctx *gin.Context) {
	req := new(v1.CalculateDrivingLineForm)
	if err := ctx.ShouldBindJSON(req); err != nil {
		v1.HandleError(ctx, http.StatusBadRequest, v1.ErrBadRequest, nil)
		return
	}
	drivingLineVo, err := h.orderService.CalculateDrivingLine(ctx, req)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, drivingLineVo)
}

// GetOrderServiceLastLocation 代驾服务：获取订单服务最后一个位置信息
func (h *OrderHandler) GetOrderServiceLastLocation(ctx *gin.Context) {

}

// FindCustomerOrderPage 获取乘客订单分页列表
func (h *OrderHandler) FindCustomerOrderPage(ctx *gin.Context) {
	customerId := ctx.GetInt64("ID")
	pageStr := ctx.Param("page")
	limitStr := ctx.Param("limit")
	page, err := strconv.Atoi(pageStr)
	limit, err2 := strconv.Atoi(limitStr)
	if err != nil || err2 != nil {
		v1.HandleError(ctx, http.StatusBadRequest, v1.ErrBadRequest, nil)
		return
	}
	orderPageVo, err := h.orderService.FindCustomerOrderPage(ctx, customerId, page, limit)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, orderPageVo)
}

// CreateWxPayment 创建微信支付
func (h *OrderHandler) CreateWxPayment(ctx *gin.Context) {
	req := new(v1.CreateWxPaymentForm)
	if err := ctx.ShouldBindJSON(req); err != nil {
		v1.HandleError(ctx, http.StatusBadRequest, v1.ErrBadRequest, nil)
		return
	}
	wxPrepayVo, err := h.paymentService.CreateWxPayment(ctx, req)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, wxPrepayVo)
}

// QueryPayStatus 支付状态查询
func (h *OrderHandler) QueryPayStatus(ctx *gin.Context) {
	orderNo := ctx.Param("orderNo")
	payStatus, err := h.paymentService.QueryPayStatus(ctx, orderNo)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, v1.ErrInternalServerError, nil)
		return
	}
	v1.HandleSuccess(ctx, payStatus)
}